home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
MACD 5
/
MACD 5.bin
/
workbench
/
tools
/
czesc_3
/
reminder
/
src
/
events.c
< prev
next >
Wrap
C/C++ Source or Header
|
1993-04-19
|
12KB
|
462 lines
/* Event handling routines for Reminder */
/* $Id: Events.c,v 1.14 1993/04/18 21:54:08 Matti_Rintala Exp $ */
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <time.h>
#include <exec/types.h>
#include <exec/lists.h>
#include <exec/exec.h>
#include <libraries/reqtools.h>
#ifdef __SASC
#include <proto/exec.h>
#include <proto/reqtools.h>
#endif
#ifdef _DCC
#include <clib/exec_protos.h>
#include <clib/reqtools_protos.h>
#endif
#include "Globals.h"
#include "CalcDate.h"
#include "Events.h"
static int checkdate(void);
static void makeentry(char *entry, short day, short month, short year,
short wday, const char *text);
static int AddEventlist(struct EventNode *newevent);
/* Eventlist holds the event database, initially empty */
static struct List Eventlist = {
(struct Node *)&Eventlist.lh_Tail,
NULL,
(struct Node *)&Eventlist.lh_Head
};
static time_t today; /* Date of current day (initialized in LoadEvents) */
static void DeleteEventlist(void);
/* InitEvents initializes the events database */
struct List *InitEvents(void) {
/* Only ensure that Eventlist is deleted on exit */
atexit(DeleteEventlist);
/* Return pointer to Eventlist */
return &Eventlist;
}
static void DeleteEventlist(void) {
struct EventNode *node;
while ((node = (struct EventNode *)RemTail(&Eventlist)) != NULL)
free(node);
eventno = 0; /* There are no events now */
}
/* NewEvent makes a new, clear event */
void NewEvent(void) {
/* Ask for confirmation if event in gadgets has been edited */
if (edited) {
if (!rtEZRequestTags("You have edited\nthe current event.\nAbandon changes?",
"_Yes|Oh, _no!", NULL, NULL, RT_LockWindow, (Tag)TRUE,
RT_Underscore, (Tag)'_', RTEZ_DefaultResponse, (Tag)0,
TAG_END)) {
/* If user does not want to abandon changes */
return;
}
}
/* Initialize all variables */
day = month = year = wday = before = after = 0;
autodelete = FALSE; grouped = FALSE;
swdaytxt = NULL;
mode = AREXXNMODE;
text[0] = arexxport[0] = arexxcom[0] = '\0';
event = ~0; /* No event selected */
edited = FALSE; /* Nothing edited now */
}
/* AddEvent adds a new event to list */
struct List *AddEvent(void) {
struct EventNode *newevent;
/* Check that the date is correct */
if (!checkdate()) {
/* If not, tell the user that */
rtEZRequestTags("Cannot add event,\ninvalid date.", "OK", NULL, NULL,
RT_LockWindow, (Tag)TRUE, TAG_END);
/* Return with unchanged list */
return &Eventlist;
}
/* Make a new list node */
if ((newevent = malloc(sizeof(struct EventNode))) == NULL) {
rtEZRequestTags("Cannot get memory\nfor new event!", "OK", NULL, NULL,
RT_LockWindow, (Tag)TRUE, TAG_END);
return &Eventlist;
}
/* Generate entry text */
makeentry(newevent->entry, day, month, year, wday, text);
newevent->node.ln_Name = newevent->entry;
/* Set Acknowledgement date to 1-Jan-1990 */
newevent->aday = 1; newevent->amonth = 1; newevent->ayear = 1990;
/* Set other fields from globals */
newevent->day = day; newevent->month = month; newevent->year = year;
newevent->wday = wday;
newevent->before = before; newevent->after = after;
newevent->autodelete = autodelete;
strncpy(newevent->text, text, TEXTLEN);
strncpy(newevent->arexxcom, arexxcom, AREXXCOMLEN);
strncpy(newevent->arexxport, arexxport, AREXXPORTLEN);
newevent->mode = mode | (grouped ? GROUPEDMASK : 0);
/* Add new entry */
event = AddEventlist(newevent);
changed = 1; /* Database has changed */
eventno++; /* One more event now exists */
edited = FALSE; /* Nothing has been edited now */
/* Return pointer to list */
return &Eventlist;
}
/* Getevent gets data from selected event */
int GetEvent(void) {
struct EventNode *node;
int i;
/* Ask for confirmation if event in gadgets has been edited */
if (edited) {
if (!rtEZRequestTags("You have edited\nthe current event.\nAbandon changes?",
"_Yes|Oh, _no!", NULL, NULL, RT_LockWindow, (Tag)TRUE,
RT_Underscore, (Tag)'_', RTEZ_DefaultResponse, (Tag)0,
TAG_END)) {
/* If user does not want to abandon changes */
return FALSE;
}
}
/* First find the appropriate node */
node = (struct EventNode *)Eventlist.lh_Head;
for (i = 0 ; i < event; i++)
node = (struct EventNode *)node->node.ln_Succ;
/* Then get the appropriate data */
wday = node->wday; day = node->day; month = node->month; year = node->year;
before = node->before; after = node->after;
autodelete = node->autodelete;
strncpy(text, node->text, TEXTLEN);
strncpy(arexxcom, node->arexxcom, AREXXCOMLEN);
strncpy(arexxport, node->arexxport, AREXXPORTLEN);
mode = node->mode & ~GROUPEDMASK;
grouped = ((node->mode & GROUPEDMASK) != 0);
edited = FALSE; /* Nothing has been edited */
return TRUE;
}
/* UpdateEvent updates an existing event */
struct List *UpdateEvent(void) {
struct EventNode *node;
int i;
/* First find the appropriate node */
node = (struct EventNode *)Eventlist.lh_Head;
for (i = 0 ; i < event; i++)
node = (struct EventNode *)node->node.ln_Succ;
/* Remove the node from EventList */
Remove((struct Node *)node);
eventno--;
/* Generate entry text */
makeentry(node->entry, day, month, year, wday, text);
node->node.ln_Name = node->entry;
/* Set Acknowledgement date to 1-Jan-1990 */
node->aday = 1; node->amonth = 1; node->ayear = 1990;
/* Set other fields from globals */
node->day = day; node->month = month; node->year = year;
node->wday = wday;
node->before = before; node->after = after;
node->autodelete = autodelete;
strncpy(node->text, text, TEXTLEN);
strncpy(node->arexxcom, arexxcom, AREXXCOMLEN);
strncpy(node->arexxport, arexxport, AREXXPORTLEN);
node->mode = mode | (grouped ? GROUPEDMASK : 0);
/* Add event back to list */
event = AddEventlist(node);
eventno++;
changed = 1; /* Database has changed */
edited = FALSE; /* Nothing has been edited */
return &Eventlist;
}
/* RemoveEvent removes an existing event */
struct List *RemoveEvent(void) {
struct EventNode *node;
int i;
/* First find the appropriate node */
node = (struct EventNode *)Eventlist.lh_Head;
for (i = 0 ; i < event; i++)
node = (struct EventNode *)node->node.ln_Succ;
/* Remove the node */
Remove((struct Node *)node);
/* Free the memory */
free(node);
changed = 1; /* Database has changed */
eventno--; /* Now there are one less events */
return &Eventlist;
}
/* LoadEvents loads the event database from file. It returns TRUE if it fails. */
int LoadEvents(const char *filename) {
FILE *infile;
struct EventNode *node;
/* Get todays date */
gettoday(&today);
/* Try to open the file */
if ((infile = fopen(filename, "rb")) == NULL)
return TRUE;
/* Skip the timestamp */
fseek(infile, sizeof(time_t), SEEK_SET);
/* Read events from file */
while (TRUE) {
/* Get memory for event */
if ((node = malloc(sizeof(struct EventNode))) == NULL) {
rtEZRequestTags("Insufficient memory!", "OK", NULL, NULL,
RT_LockWindow, (Tag)TRUE, TAG_END);
break;
}
/* Read event part of it from file */
while (TRUE) {
fread(SAVEADDR(node), 1, SAVELEN(node), infile);
/* If end-of-file occurred, stop looping */
if (feof(infile))
break;
/* Stop looping also, if event is not deleted */
if (node->mode != DELETEDMODE)
break;
else
changed = 2; /* Deleted entrys should be swept away */
}
/* If end-of-file occurred, stop looping */
if (feof(infile))
break;
/* Check mode (for database files generated with Reminder V1.00) */
if ((node->mode & ~GROUPEDMASK) != AREXXCMODE &&
(node->mode & ~GROUPEDMASK) != AREXXSMODE &&
(node->mode & ~GROUPEDMASK) != AREXXNMODE) {
/* Invalid mode, use No ARexx, no grouping and empty Port and Com fields */
node->mode = AREXXNMODE;
node->arexxcom[0] = node->arexxport[0] = '\0';
}
/* Calculate entry text */
makeentry(node->entry, node->day, node->month, node->year, node->wday,
node->text);
/* Set name of event and add it to Eventlist */
node->node.ln_Name = node->entry;
AddEventlist(node);
eventno++; /* One more event */
}
/* Free the extra node left (freeing NULL is allowed) */
free(node);
fclose(infile);
return FALSE;
}
/* SaveEvents saves event database to file. It returns TRUE if it fails. */
int SaveEvents(const char *filename) {
FILE *outfile;
struct EventNode *node;
BOOL success = TRUE;
struct tm tm_stamp = {0, 0, 0, 1, 0, 90, 0, 0, 0};
time_t stamp;
/* First try to open the file */
if ((outfile = fopen(filename, "wb")) == NULL)
return 1;
/* Write timestamp for 1.1.1990 */
stamp = mktime(&tm_stamp);
if (fwrite(&stamp, 1, sizeof(time_t), outfile) != sizeof(time_t)) {
success = FALSE;
}
else {
node = (struct EventNode *)Eventlist.lh_Head;
for (; node->node.ln_Succ != NULL;
node = (struct EventNode *)node->node.ln_Succ) {
/* Write the node information to file */
if (fwrite(SAVEADDR(node), 1, SAVELEN(node), outfile) != SAVELEN(node)) {
/* If failed, abort */
success = FALSE;
break;
}
}
}
/* Close the file and exit */
fclose(outfile);
return !success;
}
static short monthlist[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
/* checkdate checks that the date is valid */
static int checkdate(void) {
short testyear, testmonth;
/* Check month */
if (month > 12)
return 0;
/* If day is ANY, date is ok */
if (day == 0)
return 1;
/* Get appropiate values for test variables */
if (year == 0) testyear = 1996; /* Leap year */
else testyear = year;
if (month == 0) testmonth = 1; /* Month with 31 days */
else testmonth = month;
/* Check day */
if (day > (monthlist[testmonth-1] + ((testmonth == 2 && testyear%4 == 0) ?
((testyear%400 == 0) ? 0 : 1) :
0)))
return 0;
return 1;
}
/* makeentry makes an appropriate entry line for Eventlist gadget */
static void makeentry(char *entrystart, short day, short month, short year,
short wday, const char *text) {
char *entry = entrystart;
/* Start with day of the week */
/* If we have a non-repeating date with ANY weekday, show the weekday + colon */
if (day != 0 && month != 0 && year != 0 && wday == 0) {
strncpy(entry, wdayabbrv+4*weekday(day, month, year), 3);
entry += 3;
*entry++ = ':';
}
else {
strncpy(entry, wdayabbrv+4*wday, 3);
entry += 3; /* Skip the day */
*entry++ = ' ';
}
/* If day is ANY, use **, otherwise the day number */
if (day == 0) {
*entry++ = '*';
*entry++ = '*';
}
else {
sprintf(entry, "%02d", day);
entry += 2; /* Skip over the number */
}
*entry++ = '-';
/* Then month name */
strncpy(entry, monthabbrv+4*month, 3);
entry += 3; /* Skip over month */
*entry++ = '-';
/* Then year */
if (year == 0) {
*entry++ = '*';
*entry++ = '*';
*entry++ = '*';
*entry++ = '*';
}
else {
sprintf(entry, "%4d", year);
entry += 4; /* Skip over year */
}
*entry++ = ' ';
/* Then copy rest with text */
strncpy(entry, text, ENTRYLEN-(entry-entrystart));
}
/* AddEventlist finds the correct place for event and adds it to list.
It returns the place of the event in the list */
static int AddEventlist(struct EventNode *newevent) {
int i;
struct EventNode *node;
/* Calculate next occurrence of event */
makedate(&newevent->next_date, &today, newevent->day, newevent->month,
newevent->year, newevent->wday);
/* Find place for event, starting form the head of list */
node = (struct EventNode *)Eventlist.lh_Head;
for (i = 0; i < eventno; i++, node = (struct EventNode *)node->node.ln_Succ) {
/* If event is earlier than this, add new event before it */
if (newevent->next_date < node->next_date) {
Insert(&Eventlist, (struct Node *)newevent, node->node.ln_Pred);
return i; /* Return place of event */
}
}
/* If we got this far, event must be added to the end of the list */
AddTail(&Eventlist, (struct Node *)newevent);
return eventno; /* Event is the last one */
}